home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 1.iso
/
toolbox
/
src
/
exampleCode
/
opengl
/
xlib
/
tline.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-11-11
|
15KB
|
666 lines
/*
* (c) Copyright 1994, Silicon Graphics, Inc.
* ALL RIGHTS RESERVED
*
* Permission to use, copy, modify, and distribute this software for
* any purpose and without fee is hereby granted, provided that the above
* copyright notice appear in all copies and that both the copyright notice
* and this permission notice appear in supporting documentation, and that
* the name of Silicon Graphics, Inc. not be used in advertising
* or publicity pertaining to distribution of the software without specific,
* written prior permission.
*
* THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
* AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
* FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
* GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
* SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
* KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
* LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
* THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC. HAS BEEN
* ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
* POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
*
* U.S. GOVERNMENT RESTRICTED RIGHTS LEGEND
* Use, duplication, or disclosure by the Government is subject to
* restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
* (c)(1)(ii) of the Rights in Technical Data and Computer Software
* clause at DFARS 252.227-7013 and/or in similar or successor
* clauses in the FAR or the DOD or NASA FAR Supplement.
* Unpublished-- rights reserved under the copyright laws of the
* United States. Contractor/manufacturer is Silicon Graphics,
* Inc., 2011 N. Shoreline Blvd., Mountain View, CA 94039-7311.
*
* OpenGL(TM) is a trademark of Silicon Graphics, Inc.
*/
#include <GL/glx.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <X11/keysym.h>
static int RGB_SB_attributes[] = {
GLX_RGBA,
GLX_RED_SIZE, 1,
GLX_GREEN_SIZE, 1,
GLX_BLUE_SIZE, 1,
GLX_DEPTH_SIZE, 1,
GLX_STENCIL_SIZE, 1,
None,
};
static int RGB_DB_attributes[] = {
GLX_RGBA,
GLX_RED_SIZE, 1,
GLX_GREEN_SIZE, 1,
GLX_BLUE_SIZE, 1,
GLX_DOUBLEBUFFER,
GLX_DEPTH_SIZE, 1,
GLX_STENCIL_SIZE, 1,
None,
};
static int CI_SB_attributes[] = {
GLX_DEPTH_SIZE, 1,
GLX_STENCIL_SIZE, 1,
None,
};
static int CI_DB_attributes[] = {
GLX_DOUBLEBUFFER,
GLX_DEPTH_SIZE, 1,
GLX_STENCIL_SIZE, 1,
None,
};
#define SETCOLOR(x) if (rgb) glColor3fv(rgbMap[x]); else glIndexf(x)
enum {
BLACK = 0,
RED,
GREEN,
YELLOW,
BLUE,
MAGENTA,
CYAN,
WHITE
};
#define COLOR_OFFSET 16
static float rgbMap[8][3] = {
{0, 0, 0},
{1, 0, 0},
{0, 1, 0},
{1, 1, 0},
{0, 0, 1},
{1, 0, 1},
{0, 1, 1},
{1, 1, 1}
};
Display *dpy;
Colormap cmap;
Window window;
int rgb = 1;
int doubleBuf = 1;
int W = 300;
int H = 300;
static GLint indexBits;
static long ci = YELLOW;
static GLboolean dither = GL_TRUE;
static GLboolean fragment = GL_FALSE;
static GLboolean smoothModel = GL_TRUE;
static long mode1, mode2;
static int blending;
static float size;
static float pntA[3] = {-165, 0, -0.5};
static float pntB[3] = {-60, 0, -0.5};
static float pntC[3] = {-40, -50, -0.5};
static float pntD[3] = {30, 60, -0.5};
static float pntAAB[3] = {-150, 0, -0.5};
static float pntABA[3] = {-140, 0, -0.5};
static float pntABB[3] = {-120, 0, -0.5};
static float pntBAA[3] = {-100, 0, -0.5};
static float pntBAB[3] = {-80, 0, -0.5};
static float pntBBA[3] = {-70, 0, -0.5};
static float zrot = 0.0;
static float dzrot = 0.0;
static int stenciling = 0;
static int depthtest = 1;
static int alwayspass = 0;
static int depthMask = 0;
static void SetUpColorMap(void)
{
XColor *xc;
float color;
long i, j, cells;
if (indexBits < 5) return;
cells = 16;
xc = (XColor *) malloc(cells * sizeof(XColor));
for (i = 0; i < 16; i++) {
xc[i].pixel = i + COLOR_OFFSET;
xc[i].red = i * 4369;
xc[i].green = i * 4369;
xc[i].blue = 0;
xc[i].flags = DoRed | DoGreen | DoBlue;
}
XStoreColors(dpy, cmap, xc, cells);
free((void *) xc);
}
static void Init(void)
{
if (!rgb) {
glGetIntegerv(GL_INDEX_BITS, &indexBits);
SetUpColorMap();
}
mode1 = 0;
mode2 = 0;
size = 1;
glViewport(10, 10, W-20, H-20);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-175, 175, -175, 175, -1, 1);
glMatrixMode(GL_MODELVIEW);
}
static void Redraw(void)
{
long i;
if (dzrot != 0.0) {
zrot += dzrot;
}
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
glLineWidth(3);
glDisable(GL_LINE_STIPPLE);
glDisable(GL_LINE_SMOOTH);
glDisable(GL_BLEND);
if (depthtest) {
glClearDepth(1.0);
glClear(GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
if (alwayspass) {
glDepthFunc(GL_ALWAYS);
} else {
glDepthFunc(GL_LESS);
}
SETCOLOR(MAGENTA);
glBegin(GL_LINES);
for (i = -8; i <= 8; i++) {
glVertex3f(i*20, -175, 0);
glVertex3f(i*20, 175, 0);
}
if (depthMask) {
glEnd();
glDepthMask(GL_FALSE);
glBegin(GL_LINES);
}
for (i = -8; i <= 8; i++) {
glVertex3f(-175, i*20, 0);
glVertex3f( 175, i*20, 0);
}
glEnd();
if (depthMask) {
glDepthMask(GL_TRUE);
}
}
if (stenciling) {
SETCOLOR(BLACK);
glClearStencil(0);
glClear(GL_STENCIL_BUFFER_BIT);
glEnable(GL_STENCIL_TEST);
glStencilFunc(GL_ALWAYS, 1, 3);
glStencilOp(GL_KEEP, GL_INVERT, GL_REPLACE);
glBegin(GL_LINES);
for (i = -10; i <= 10; i++) {
glVertex3f(i*17, -175, -0.5);
glVertex3f(i*17, 175, -0.5);
}
for (i = -10; i <= 10; i++) {
glVertex3f(-175, i*17, -0.5);
glVertex3f( 175, i*17, -0.5);
}
glEnd();
glStencilOp(GL_KEEP, GL_KEEP, GL_INVERT);
if (depthtest) {
SETCOLOR(RED);
glStencilFunc(GL_EQUAL, 3, 3);
glDisable(GL_DEPTH_TEST);
glBegin(GL_QUADS);
glVertex3f(-175, -175, -0.5);
glVertex3f(-175, 175, -0.5);
glVertex3f( 175, 175, -0.5);
glVertex3f( 175, -175, -0.5);
glEnd();
glEnable(GL_DEPTH_TEST);
}
glStencilOp(GL_KEEP, GL_INVERT, GL_KEEP);
glStencilFunc(GL_NOTEQUAL, 1, 1);
}
glLineWidth(size);
if (mode1) {
glEnable(GL_LINE_STIPPLE);
} else {
glDisable(GL_LINE_STIPPLE);
}
glLineStipple(1, 0xF0E0);
if (blending) {
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ZERO);
}
if (mode2) {
glEnable(GL_LINE_SMOOTH);
if (mode2 > 1) {
glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
} else {
glHint(GL_LINE_SMOOTH_HINT, GL_DONT_CARE);
}
} else {
glDisable(GL_LINE_SMOOTH);
}
glPushMatrix();
glRotatef(zrot, 0,0,1);
for (i = 0; i < 360; i += 5) {
glRotatef(5.0, 0,0,1);
if (rgb) glColor3fv(rgbMap[YELLOW]); else glIndexi(ci);
glBegin(GL_LINE_STRIP);
if (fragment) {
glVertex3fv(pntA);
glVertex3fv(pntAAB);
glVertex3fv(pntABA);
glVertex3fv(pntABB);
if (rgb || !mode2) {
SETCOLOR(CYAN);
}
glVertex3fv(pntBAA);
glVertex3fv(pntBAB);
glVertex3fv(pntBBA);
glVertex3fv(pntB);
} else {
glVertex3fv(pntA);
if (rgb || !mode2) {
SETCOLOR(CYAN);
}
glVertex3fv(pntB);
}
glEnd();
SETCOLOR(GREEN);
}
glPopMatrix();
glFlush();
if (depthtest) {
glDisable(GL_DEPTH_TEST);
if (stenciling) {
SETCOLOR(WHITE);
glStencilFunc(GL_EQUAL, 3, 3);
glBegin(GL_QUADS);
glVertex3f(-175, -175, -0.5);
glVertex3f(-175, 175, -0.5);
glVertex3f( 175, 175, -0.5);
glVertex3f( 175, -175, -0.5);
glEnd();
}
}
if (stenciling) {
glDisable(GL_STENCIL_TEST);
}
if (doubleBuf) {
glXSwapBuffers(dpy, window);
}
}
static void Usage(void)
{
fprintf(stderr, "Usage: program [-c] [-s] [-geometry WxH+X+Y]\n");
fprintf(stderr, " -c run in color index mode\n");
fprintf(stderr, " -s run in singlebuffer mode\n");
fprintf(stderr, " -geometry window size and location\n");
exit(1);
}
static Bool WaitForMapNotify(Display *d, XEvent *e, char *arg)
{
if ((e->type == MapNotify) && (e->xmap.window == (Window) arg)) {
return GL_TRUE;
}
return GL_FALSE;
}
int main(int argc, char** argv)
{
XVisualInfo *vi;
XSetWindowAttributes swa;
GLXContext cx;
XEvent event;
GLboolean needDisplay;
XColor black;
int i;
XSizeHints sizehints;
char *geometry = NULL;
rgb = 1;
for (i = 1; i < argc; i++) {
if (argv[i][0] == '-') {
if (strcmp(argv[i], "-geometry") == 0) {
i++;
geometry = argv[i];
} else switch (argv[i][1]) {
case 'c':
rgb = GL_FALSE;
break;
case 's':
doubleBuf = 0;
break;
default:
Usage();
}
} else {
Usage();
}
}
dpy = XOpenDisplay(0);
if (!dpy) {
fprintf(stderr, "Can't connect to display \"%s\"\n", getenv("DISPLAY"));
return -1;
}
vi = glXChooseVisual(dpy, DefaultScreen(dpy),
doubleBuf ? (rgb ? RGB_DB_attributes : CI_DB_attributes) :
(rgb ? RGB_SB_attributes : CI_SB_attributes));
if (!vi) {
fprintf(stderr, "No singlebuffered rgba visual on \"%s\"\n",
getenv("DISPLAY"));
return -1;
}
sizehints.flags = PPosition | PSize;
sizehints.width = W;
sizehints.height = H;
sizehints.x = 10;
sizehints.y = 10;
if(geometry) {
int flags, x, y, width, height;
flags = XParseGeometry(geometry, &x, &y,
(unsigned int *)&width,
(unsigned int *)&height);
if(WidthValue & flags) {
sizehints.flags |= USSize;
sizehints.width = width;
W = width;
}
if(HeightValue & flags) {
sizehints.flags |= USSize;
sizehints.height = height;
H = height;
}
if(XValue & flags) {
if(XNegative & flags)
x = DisplayWidth(dpy, DefaultScreen(dpy)) + x
- sizehints.width;
sizehints.flags |= USPosition;
sizehints.x = x;
}
if(YValue & flags) {
if(YNegative & flags)
y = DisplayHeight(dpy, DefaultScreen(dpy)) + y
- sizehints.height;
sizehints.flags |= USPosition;
sizehints.y = y;
}
}
cmap = XCreateColormap(dpy, RootWindow(dpy, vi->screen), vi->visual,
rgb ? AllocNone : AllocAll);
if (!rgb) {
XColor buf;
int i;
buf.flags = DoRed | DoGreen | DoBlue;
/* Init color map */
for (i=0; i<16; i++) {
buf.pixel = i;
buf.blue = (i & 4) ? 65535 : 0;
buf.green = (i & 2) ? 65535 : 0;
buf.red = (i & 1) ? 65535 : 0;
if (i > 8) {
buf.red /= 2;
buf.green /= 2;
buf.blue /= 2;
}
XStoreColor(dpy, cmap, &buf);
}
}
swa.border_pixel = 0;
swa.background_pixmap = None;
swa.colormap = cmap;
swa.event_mask = ExposureMask | StructureNotifyMask | KeyPressMask
| KeyReleaseMask;
window = XCreateWindow(dpy, RootWindow(dpy, vi->screen),
sizehints.x, sizehints.y,
sizehints.width, sizehints.height,
0, vi->depth, InputOutput, vi->visual,
CWBackPixmap|CWBorderPixel|CWColormap|CWEventMask,
&swa);
XSetStandardProperties(dpy, window, "tline", "tline", None,
argv, argc, &sizehints);
XSetWMColormapWindows(dpy, window, &window, 1);
XMapWindow(dpy, window);
XIfEvent(dpy, &event, WaitForMapNotify, (char*)window);
cx = glXCreateContext(dpy, vi, 0, GL_TRUE);
if (!glXMakeCurrent(dpy, window, cx)) {
fprintf(stderr, "Can't make window current to context\n");
return -1;
}
Init();
needDisplay = GL_TRUE;
for (;;) {
if (XPending(dpy) || dzrot == 0.0) do {
XNextEvent(dpy, &event);
switch (event.type) {
case Expose:
needDisplay = GL_TRUE;
break;
case ConfigureNotify:
W = event.xconfigure.width;
H = event.xconfigure.height;
glViewport(10, 10, W-20, H-20);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-175, 175, -175, 175, -1, 1);
glMatrixMode(GL_MODELVIEW);
needDisplay = GL_TRUE;
break;
case KeyPress:
{
char buf[100];
int rv;
KeySym ks;
GLboolean setNeed = GL_TRUE;
rv = XLookupString(&event.xkey, buf, sizeof(buf), &ks, 0);
switch (ks) {
case XK_Escape:
exit(0);
case XK_Y:
case XK_y:
blending = 1-blending;
break;
case XK_G:
case XK_g:
if (dzrot != 0.0) {
dzrot = 0.0;
} else {
dzrot = 0.2;
}
break;
case XK_q:
case XK_Q:
mode1 = 1;
break;
case XK_w:
case XK_W:
mode1 = 0;
break;
case XK_e:
case XK_E:
mode2 = 2;
ci = COLOR_OFFSET;
break;
case XK_r:
case XK_R:
mode2 = 1;
ci = COLOR_OFFSET;
break;
case XK_t:
case XK_T:
mode2 = 0;
ci = YELLOW;
break;
case XK_a:
case XK_A:
if (mode2) {
size += 0.25;
} else {
size ++;
}
break;
case XK_z:
case XK_Z:
if (mode2) {
size -= 0.25;
} else {
size --;
}
if (size < 1) {
size = 1;
}
break;
case XK_D:
case XK_d:
dither = !dither;
if (dither) {
glEnable(GL_DITHER);
printf("Dithering on\n");
} else {
glDisable(GL_DITHER);
printf("Dithering off\n");
}
break;
case XK_F:
case XK_f:
fragment = !fragment;
if (fragment) {
printf("Fragmenting\n");
} else {
printf("No fragmenting\n");
}
break;
case XK_S:
case XK_s:
smoothModel = !smoothModel;
if (smoothModel) {
printf("Smooth shading\n");
glShadeModel(GL_SMOOTH);
} else {
printf("Flat shading\n");
glShadeModel(GL_FLAT);
}
break;
case XK_X:
case XK_x:
stenciling = !stenciling;
if (stenciling) {
printf("Stenciling\n");
} else {
printf("Not stenciling\n");
}
break;
case XK_C:
case XK_c:
depthtest = !depthtest;
if (depthtest) {
printf("Depth testing\n");
} else {
printf("No depth testing\n");
}
break;
case XK_V:
case XK_v:
alwayspass = !alwayspass;
if (alwayspass) {
printf("Always pass\n");
} else {
printf("Not always pass\n");
}
break;
case XK_B:
case XK_b:
depthMask = !depthMask;
if (depthMask) {
printf("Depth writes masked for horizontal lines\n");
} else {
printf("Depth writes not masked\n");
}
break;
default:
setNeed = GL_FALSE;
break;
}
if (setNeed) needDisplay = GL_TRUE;
}
break;
}
} while (XPending(dpy) != 0);
if (dzrot != 0.0 || needDisplay) {
needDisplay = GL_FALSE;
Redraw();
}
}
}